package sq

import (
	"gitee.com/gopher2011/sqlx/reflectx"
	"reflect"
)

// ReflectMapper 数据库字段与结构体属性的反射映射器。
type ReflectMapper struct {
	mapper *reflectx.Mapper
}

// NewReflectMapper 输入<tagName>返回一个 反射映射器对象。
func NewReflectMapper(tagName string) *ReflectMapper {
	return &ReflectMapper{
		mapper: reflectx.NewMapper(tagName),
	}
}

// FieldByName 通过其映射名称返回字段，即 reflect.Value。
//  如果v的Kind不是Struct或v不可间接访问结构体，则会 panic。
//  如果找不到名称，则返回零值。
func (r *ReflectMapper) FieldByName(v reflect.Value, name string) reflect.Value {
	return r.mapper.FieldByName(v, name)
}

// FieldMap 返回映射器对字段名称的映射以反映值。
//  如果 v不是结构体指针，或者不是结果体，则会panic。
func (r *ReflectMapper) FieldMap(v reflect.Value) map[string]reflect.Value {
	v = reflect.Indirect(v)

	ret := map[string]reflect.Value{}
	tm := r.mapper.TypeMap(v.Type())
	for tagName, fi := range tm.Names {
		//fmt.Println(tagName,fi.Parent.Zero.Kind(),fi.Parent.Field.Anonymous)
		if (fi.Parent.Zero.Kind() == reflect.Struct || (fi.Zero.Kind() == reflect.Ptr && fi.Zero.Type().Elem().Kind() == reflect.Struct)) && !fi.Parent.Field.Anonymous {
			continue
		}
		ret[tagName] = reflectx.FieldByIndexes(v, fi.Index)
	}
	return ret
}
